# -*- coding: utf-8 -*-
# 设备相关类定义

import cv2
import numpy as np
from PyQt5.QtCore import QThread, pyqtSignal, QTimer, Qt, QRectF
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QGraphicsScene


class IntegratedCamera:
    """笔记本内置摄像头类"""
    
    def __init__(self):
        self.camera = None
        self.is_connected = False
        self.is_capturing = False
        # 移除预设参数，使用None表示未设置
        self.frame_width = None
        self.frame_height = None
        self.fps = None
        self.camera_index = 0  # 内置摄像头通常索引为0
        
    def connect(self, camera_index=0):
        """连接摄像头，完全使用默认参数"""
        try:
            # 先释放可能存在的摄像头连接
            if self.camera:
                self.camera.release()
                self.camera = None
            
            # 尝试打开摄像头
            self.camera = cv2.VideoCapture(camera_index, cv2.CAP_DSHOW)  # 使用DirectShow后端
            if self.camera.isOpened():
                self.is_connected = True
                self.camera_index = camera_index
                
                # 等待摄像头初始化
                import time
                time.sleep(0.5)
                
                # 完全使用摄像头默认设置，不进行任何参数设置
                print(f"使用摄像头 {camera_index} 的完全默认参数")
                
                # 测试读取一帧
                ret, test_frame = self.camera.read()
                if ret and test_frame is not None:
                    # 获取默认的分辨率和帧率
                    actual_width = test_frame.shape[1]
                    actual_height = test_frame.shape[0]
                    default_fps = self.camera.get(cv2.CAP_PROP_FPS)
                    
                    # 更新内部变量为实际检测到的值
                    self.frame_width = actual_width
                    self.frame_height = actual_height
                    self.fps = default_fps
                    
                    print(f"摄像头 {camera_index} 连接成功")
                    print(f"检测到的默认分辨率: {actual_width}x{actual_height}")
                    print(f"检测到的默认帧率: {default_fps:.1f} FPS")
                    print("注意：所有参数都使用摄像头默认值，未进行任何设置")
                    return True
                else:
                    print(f"摄像头 {camera_index} 连接成功但无法读取图像")
                    self.camera.release()
                    self.camera = None
                    self.is_connected = False
                    return False
            else:
                print(f"无法连接摄像头 {camera_index}")
                return False
        except Exception as e:
            print(f"连接摄像头时出错: {e}")
            if self.camera:
                self.camera.release()
                self.camera = None
            self.is_connected = False
            return False
    
    def disconnect(self):
        """断开摄像头连接"""
        if self.camera:
            self.camera.release()
            self.camera = None
        self.is_connected = False
        self.is_capturing = False
        print("摄像头已断开连接")
    
    def capture_frame(self):
        """捕获一帧图像"""
        if not self.is_connected or self.camera is None:
            print("摄像头未连接")
            return None
        
        try:
            ret, frame = self.camera.read()
            if ret and frame is not None:
                return frame
            else:
                print("无法捕获图像帧")
                return None
        except Exception as e:
            print(f"捕获图像帧时出错: {e}")
            return None
    
    def start_capture(self):
        """开始连续捕获"""
        if not self.is_connected:
            print("摄像头未连接")
            return False
        
        self.is_capturing = True
        print("开始连续捕获")
        return True
    
    def stop_capture(self):
        """停止连续捕获"""
        self.is_capturing = False
        print("停止连续捕获")
    
    def get_camera_info(self):
        """获取摄像头信息（只使用实际检测到的参数）"""
        if not self.is_connected:
            return None
        
        try:
            # 读取一帧来获取实际帧尺寸
            actual_width = None
            actual_height = None
            
            try:
                ret, test_frame = self.camera.read()
                if ret and test_frame is not None:
                    actual_width = test_frame.shape[1]
                    actual_height = test_frame.shape[0]
                else:
                    print("无法读取摄像头帧来获取实际尺寸")
                    return None
            except Exception as e:
                print(f"获取实际帧尺寸时出错: {e}")
                return None
            
            # 尝试多种方式获取帧率
            current_fps = 0.0
            
            # 方法1: OpenCV报告的帧率
            cv_fps = self.camera.get(cv2.CAP_PROP_FPS)
            if cv_fps > 0:
                current_fps = cv_fps
                print(f"OpenCV报告帧率: {cv_fps:.1f} FPS")
            
            # 方法2: 通过实际读取帧来测试帧率
            if current_fps <= 0 or current_fps > 1000:  # 如果OpenCV报告异常
                print("通过实际读取测试帧率...")
                import time
                test_frames = 50
                start_time = time.time()
                
                for i in range(test_frames):
                    ret, frame = self.camera.read()
                    if not ret or frame is None:
                        break
                
                test_time = time.time() - start_time
                if test_time > 0:
                    test_fps = test_frames / test_time
                    current_fps = test_fps
                    print(f"实际测试帧率: {test_fps:.1f} FPS")
            
            # 方法3: 尝试获取其他帧率属性
            if current_fps <= 0:
                try:
                    # 尝试不同的帧率属性
                    fps_props = [
                        cv2.CAP_PROP_FPS,
                        cv2.CAP_PROP_FOURCC,
                        cv2.CAP_PROP_FRAME_COUNT
                    ]
                    
                    for prop in fps_props:
                        value = self.camera.get(prop)
                        if value > 0 and value < 1000:  # 合理的帧率范围
                            current_fps = value
                            print(f"从属性 {prop} 获取帧率: {value:.1f} FPS")
                            break
                except Exception as e:
                    print(f"获取帧率属性时出错: {e}")
            
            # 如果仍然没有获取到帧率，使用默认值
            if current_fps <= 0:
                current_fps = 30.0  # 默认30FPS
                print("使用默认帧率: 30.0 FPS")
            
            info = {
                'width': actual_width,
                'height': actual_height,
                'fps': int(current_fps),  # 确保fps是整数
                'brightness': self.camera.get(cv2.CAP_PROP_BRIGHTNESS),
                'contrast': self.camera.get(cv2.CAP_PROP_CONTRAST),
                'saturation': self.camera.get(cv2.CAP_PROP_SATURATION),
                'using_default': True  # 标记使用默认参数
            }
            
            print(f"摄像头实际参数:")
            print(f"  分辨率: {actual_width}x{actual_height}")
            print(f"  帧率: {current_fps:.1f} FPS")
            print(f"  状态: 使用摄像头默认参数")
            
            return info
            
        except Exception as e:
            print(f"获取摄像头信息时出错: {e}")
            return None
    
    def set_resolution(self, width, height):
        """设置摄像头硬件分辨率"""
        if self.is_connected:
            try:
                print(f"正在设置摄像头硬件分辨率: {width}x{height}")
                
                # 先停止捕获
                was_capturing = self.is_capturing
                if was_capturing:
                    self.stop_capture()
                
                # 记录设置前的状态
                old_width = int(self.camera.get(cv2.CAP_PROP_FRAME_WIDTH))
                old_height = int(self.camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
                
                # 设置摄像头硬件分辨率
                # 注意：这些设置直接影响摄像头硬件，不是软件缩放
                self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, width)
                self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
                
                # 等待硬件设置生效
                import time
                time.sleep(0.2)  # 增加等待时间确保硬件设置生效
                
                # 验证硬件设置是否成功
                ret, test_frame = self.camera.read()
                if ret and test_frame is not None:
                    # 获取实际硬件返回的帧尺寸
                    actual_width = test_frame.shape[1]
                    actual_height = test_frame.shape[0]
                    
                    # 获取OpenCV报告的分辨率
                    cv_width = int(self.camera.get(cv2.CAP_PROP_FRAME_WIDTH))
                    cv_height = int(self.camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
                    
                    # 更新内部变量（使用实际硬件返回的尺寸）
                    self.frame_width = actual_width
                    self.frame_height = actual_height
                    
                    print(f"硬件分辨率设置结果:")
                    print(f"  请求分辨率: {width}x{height}")
                    print(f"  硬件返回: {actual_width}x{actual_height}")
                    print(f"  OpenCV报告: {cv_width}x{cv_height}")
                    print(f"  之前分辨率: {old_width}x{old_height}")
                    
                    # 检查设置是否成功（允许一定的误差）
                    width_match = abs(actual_width - width) <= 10
                    height_match = abs(actual_height - height) <= 10
                    
                    if width_match and height_match:
                        print(f"✓ 硬件分辨率设置成功: {actual_width}x{actual_height}")
                        
                        # 如果之前在捕获，重新开始
                        if was_capturing:
                            self.start_capture()
                        
                        return True
                    else:
                        print(f"⚠ 硬件分辨率设置部分成功:")
                        print(f"  请求: {width}x{height}")
                        print(f"  实际: {actual_width}x{actual_height}")
                        
                        # 即使不完全匹配，也更新内部变量并继续
                        if was_capturing:
                            self.start_capture()
                        
                        return False
                else:
                    print("✗ 无法读取测试帧来验证硬件分辨率设置")
                    
                    # 恢复之前的设置
                    self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, old_width)
                    self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, old_height)
                    
                    if was_capturing:
                        self.start_capture()
                    
                    return False
                    
            except Exception as e:
                print(f"✗ 设置硬件分辨率时出错: {e}")
                return False
        else:
            print("✗ 摄像头未连接，无法设置分辨率")
            return False
    
    def set_fps(self, fps):
        """设置摄像头硬件帧率"""
        if self.is_connected:
            try:
                print(f"正在设置摄像头硬件帧率: {fps} FPS")
                
                # 先停止捕获
                was_capturing = self.is_capturing
                if was_capturing:
                    self.stop_capture()
                
                # 记录设置前的状态
                old_fps = self.camera.get(cv2.CAP_PROP_FPS)
                
                # 设置摄像头硬件帧率
                # 注意：这个设置直接影响摄像头硬件，不是软件限制
                self.camera.set(cv2.CAP_PROP_FPS, fps)
                
                # 等待硬件设置生效
                import time
                time.sleep(0.2)
                
                # 验证硬件设置是否成功
                actual_fps = self.camera.get(cv2.CAP_PROP_FPS)
                
                # 更新内部变量
                self.fps = actual_fps
                
                print(f"硬件帧率设置结果:")
                print(f"  请求帧率: {fps} FPS")
                print(f"  硬件返回: {actual_fps:.1f} FPS")
                print(f"  之前帧率: {old_fps:.1f} FPS")
                
                # 检查设置是否成功（允许一定的误差）
                fps_match = abs(actual_fps - fps) < 5
                
                if fps_match:
                    print(f"✓ 硬件帧率设置成功: {actual_fps:.1f} FPS")
                else:
                    print(f"⚠ 硬件帧率设置部分成功:")
                    print(f"  请求: {fps} FPS")
                    print(f"  实际: {actual_fps:.1f} FPS")
                
                # 如果之前在捕获，重新开始
                if was_capturing:
                    self.start_capture()
                
                return fps_match
                
            except Exception as e:
                print(f"✗ 设置硬件帧率时出错: {e}")
                return False
        else:
            print("✗ 摄像头未连接，无法设置帧率")
            return False
    
    def get_supported_resolutions(self):
        """获取支持的分辨率列表"""
        if not self.is_connected:
            return []
        
        supported_resolutions = []
        test_resolutions = [
            (1920, 1080), (1280, 720), (800, 600), 
            (640, 480), (320, 240), (160, 120)
        ]
        
        for width, height in test_resolutions:
            try:
                # 临时设置分辨率
                self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, width)
                self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
                
                # 读取一帧测试
                ret, frame = self.camera.read()
                if ret and frame is not None:
                    actual_width = int(self.camera.get(cv2.CAP_PROP_FRAME_WIDTH))
                    actual_height = int(self.camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
                    
                    # 检查实际分辨率是否接近请求的分辨率
                    if (abs(actual_width - width) <= 10 and 
                        abs(actual_height - height) <= 10):
                        supported_resolutions.append((actual_width, actual_height))
            except Exception as e:
                print(f"测试分辨率 {width}x{height} 时出错: {e}")
                continue
        
        # 恢复原始分辨率
        self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, self.frame_width)
        self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, self.frame_height)
        
        return list(set(supported_resolutions))  # 去重
    
    def get_hardware_supported_resolutions(self):
        """获取摄像头硬件支持的真实分辨率列表"""
        if not self.is_connected:
            return []
        
        print("正在检测摄像头硬件支持的分辨率...")
        
        # 保存当前设置
        current_width = self.frame_width
        current_height = self.frame_height
        
        supported_resolutions = []
        
        # 测试常见的硬件分辨率
        test_resolutions = [
            (1920, 1080),  # Full HD
            (1280, 720),   # HD
            (800, 600),    # SVGA
            (640, 480),    # VGA
            (320, 240),    # QVGA
            (160, 120),    # QQVGA
            (1280, 1024),  # SXGA
            (1024, 768),   # XGA
            (720, 480),    # 480p
            (720, 576),    # 576p
        ]
        
        for width, height in test_resolutions:
            try:
                print(f"  测试分辨率: {width}x{height}")
                
                # 设置分辨率
                self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, width)
                self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
                
                # 等待设置生效
                import time
                time.sleep(0.1)
                
                # 读取多帧来确保设置稳定
                actual_width = None
                actual_height = None
                
                for i in range(3):
                    ret, frame = self.camera.read()
                    if ret and frame is not None:
                        frame_width = frame.shape[1]
                        frame_height = frame.shape[0]
                        
                        if actual_width is None:
                            actual_width = frame_width
                            actual_height = frame_height
                        elif frame_width == actual_width and frame_height == actual_height:
                            # 连续两帧尺寸一致，说明设置稳定
                            break
                        else:
                            # 尺寸不一致，继续测试
                            actual_width = frame_width
                            actual_height = frame_height
                
                if actual_width is not None and actual_height is not None:
                    # 检查是否是真正的硬件支持（不是软件缩放）
                    cv_width = int(self.camera.get(cv2.CAP_PROP_FRAME_WIDTH))
                    cv_height = int(self.camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
                    
                    # 判断是否为硬件支持的分辨率
                    is_hardware_supported = (
                        abs(actual_width - width) <= 10 and
                        abs(actual_height - height) <= 10 and
                        abs(cv_width - width) <= 10 and
                        abs(cv_height - height) <= 10
                    )
                    
                    if is_hardware_supported:
                        supported_resolutions.append({
                            'width': actual_width,
                            'height': actual_height,
                            'name': f"{actual_width}x{actual_height}",
                            'hardware': True
                        })
                        print(f"    ✓ 硬件支持: {actual_width}x{actual_height}")
                    else:
                        print(f"    ✗ 不支持: {actual_width}x{actual_height} (请求: {width}x{height})")
                
            except Exception as e:
                print(f"    测试失败: {e}")
                continue
        
        # 恢复原始设置
        self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, current_width)
        self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, current_height)
        
        # 去重并排序
        unique_resolutions = []
        seen = set()
        for res in supported_resolutions:
            key = (res['width'], res['height'])
            if key not in seen:
                seen.add(key)
                unique_resolutions.append(res)
        
        # 按分辨率大小排序（从高到低）
        unique_resolutions.sort(key=lambda x: x['width'] * x['height'], reverse=True)
        
        print(f"检测完成，找到 {len(unique_resolutions)} 个硬件支持的分辨率")
        return unique_resolutions
    
    def adjust_brightness(self, value):
        """调整亮度"""
        if self.is_connected:
            self.camera.set(cv2.CAP_PROP_BRIGHTNESS, value)
            print(f"亮度调整为: {value}")
    
    def adjust_contrast(self, value):
        """调整对比度"""
        if self.is_connected:
            self.camera.set(cv2.CAP_PROP_CONTRAST, value)
            print(f"对比度调整为: {value}")
    
    def save_image(self, frame, filename):
        """保存图像"""
        if frame is not None:
            cv2.imwrite(filename, frame)
            print(f"图像已保存为: {filename}")
            return True
        else:
            print("无法保存图像：帧为空")
            return False
    
    def convert_frame_to_qimage(self, frame):
        """将OpenCV帧转换为QImage"""
        if frame is None:
            return None
        
        # 转换颜色空间从BGR到RGB
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_frame.shape
        bytes_per_line = ch * w
        
        # 创建QImage
        q_image = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
        return q_image
    
    def convert_frame_to_qpixmap(self, frame):
        """将OpenCV帧转换为QPixmap"""
        q_image = self.convert_frame_to_qimage(frame)
        if q_image:
            return QPixmap.fromImage(q_image)
        return None
    
    @staticmethod
    def find_available_cameras(max_index=10):
        """
        查找可用的摄像头
        
        Args:
            max_index (int): 最大检测的摄像头索引
            
        Returns:
            list: 可用的摄像头索引列表
        """
        available_cameras = []
        
        for i in range(max_index):
            try:
                cap = cv2.VideoCapture(i, cv2.CAP_DSHOW)
                if cap.isOpened():
                    ret, frame = cap.read()
                    if ret and frame is not None:
                        available_cameras.append(i)
                        print(f"找到可用摄像头: 索引 {i}")
                    cap.release()
                else:
                    cap.release()
            except Exception as e:
                print(f"检测摄像头 {i} 时出错: {e}")
                continue
        
        return available_cameras


class USBCamera(IntegratedCamera):
    """USB摄像头类，继承自IntegratedCamera"""
    
    def __init__(self, camera_index=1):
        super().__init__()
        self.camera_index = camera_index
        self.camera_name = f"USB Camera {camera_index}"
        
    def connect(self, camera_index=None):
        """连接USB摄像头，完全使用默认参数"""
        if camera_index is not None:
            self.camera_index = camera_index
            
        try:
            # 尝试打开USB摄像头
            self.camera = cv2.VideoCapture(self.camera_index)
            if self.camera.isOpened():
                self.is_connected = True
                
                # 等待摄像头初始化
                import time
                time.sleep(0.5)
                
                # 完全使用摄像头默认设置，不进行任何参数设置
                print(f"使用USB摄像头 {self.camera_index} 的完全默认参数")
                
                # 测试读取一帧
                ret, test_frame = self.camera.read()
                if ret and test_frame is not None:
                    # 获取默认的分辨率和帧率
                    actual_width = test_frame.shape[1]
                    actual_height = test_frame.shape[0]
                    default_fps = self.camera.get(cv2.CAP_PROP_FPS)
                    
                    # 更新内部变量为实际检测到的值
                    self.frame_width = actual_width
                    self.frame_height = actual_height
                    self.fps = default_fps
                    
                    print(f"USB摄像头 {self.camera_index} 连接成功")
                    print(f"检测到的默认分辨率: {actual_width}x{actual_height}")
                    print(f"检测到的默认帧率: {default_fps:.1f} FPS")
                    print("注意：所有参数都使用摄像头默认值，未进行任何设置")
                    return True
                else:
                    print(f"USB摄像头 {self.camera_index} 连接成功但无法读取图像")
                    self.camera.release()
                    self.camera = None
                    self.is_connected = False
                    return False
            else:
                print(f"无法连接USB摄像头 {self.camera_index}")
                return False
        except Exception as e:
            print(f"连接USB摄像头时出错: {e}")
            return False
    
    def get_camera_info(self):
        """获取USB摄像头信息（只使用实际检测到的参数）"""
        if not self.is_connected:
            return None
        
        try:
            # 读取一帧来获取实际帧尺寸
            actual_width = None
            actual_height = None
            
            try:
                ret, test_frame = self.camera.read()
                if ret and test_frame is not None:
                    actual_width = test_frame.shape[1]
                    actual_height = test_frame.shape[0]
                else:
                    print("无法读取USB摄像头帧来获取实际尺寸")
                    return None
            except Exception as e:
                print(f"获取USB摄像头实际帧尺寸时出错: {e}")
                return None
            
            # 尝试多种方式获取帧率
            current_fps = 0.0
            
            # 方法1: OpenCV报告的帧率
            cv_fps = self.camera.get(cv2.CAP_PROP_FPS)
            if cv_fps > 0:
                current_fps = cv_fps
                print(f"OpenCV报告帧率: {cv_fps:.1f} FPS")
            
            # 方法2: 通过实际读取帧来测试帧率
            if current_fps <= 0 or current_fps > 1000:  # 如果OpenCV报告异常
                print("通过实际读取测试帧率...")
                import time
                test_frames = 50
                start_time = time.time()
                
                for i in range(test_frames):
                    ret, frame = self.camera.read()
                    if not ret or frame is None:
                        break
                
                test_time = time.time() - start_time
                if test_time > 0:
                    test_fps = test_frames / test_time
                    current_fps = test_fps
                    print(f"实际测试帧率: {test_fps:.1f} FPS")
            
            # 方法3: 尝试获取其他帧率属性
            if current_fps <= 0:
                try:
                    # 尝试不同的帧率属性
                    fps_props = [
                        cv2.CAP_PROP_FPS,
                        cv2.CAP_PROP_FOURCC,
                        cv2.CAP_PROP_FRAME_COUNT
                    ]
                    
                    for prop in fps_props:
                        value = self.camera.get(prop)
                        if value > 0 and value < 1000:  # 合理的帧率范围
                            current_fps = value
                            print(f"从属性 {prop} 获取帧率: {value:.1f} FPS")
                            break
                except Exception as e:
                    print(f"获取帧率属性时出错: {e}")
            
            # 如果仍然没有获取到帧率，使用默认值
            if current_fps <= 0:
                current_fps = 30.0  # 默认30FPS
                print("使用默认帧率: 30.0 FPS")
            
            info = {
                'width': actual_width,
                'height': actual_height,
                'fps': int(current_fps),  # 确保fps是整数
                'brightness': self.camera.get(cv2.CAP_PROP_BRIGHTNESS),
                'contrast': self.camera.get(cv2.CAP_PROP_CONTRAST),
                'saturation': self.camera.get(cv2.CAP_PROP_SATURATION),
                'using_default': True,  # 标记使用默认参数
                'camera_type': 'USB',
                'camera_index': self.camera_index,
                'camera_name': self.camera_name
            }
            
            print(f"USB摄像头实际参数:")
            print(f"  分辨率: {actual_width}x{actual_height}")
            print(f"  帧率: {current_fps:.1f} FPS")
            print(f"  状态: 使用摄像头默认参数")
            
            return info
            
        except Exception as e:
            print(f"获取USB摄像头信息时出错: {e}")
            return None


class CameraThread(QThread):
    """摄像头线程类，用于在后台处理摄像头数据"""
    
    frame_ready = pyqtSignal(object)  # 发送帧数据信号
    error_occurred = pyqtSignal(str)  # 发送错误信号
    
    def __init__(self, camera):
        super().__init__()
        self.camera = camera
        self.running = False
    
    def run(self):
        """线程运行方法"""
        self.running = True
        consecutive_errors = 0
        max_consecutive_errors = 10
        
        while self.running:
            if self.camera.is_connected and self.camera.is_capturing:
                frame = self.camera.capture_frame()
                if frame is not None:
                    self.frame_ready.emit(frame)
                    consecutive_errors = 0  # 重置错误计数
                else:
                    consecutive_errors += 1
                    if consecutive_errors >= max_consecutive_errors:
                        self.error_occurred.emit("连续多次无法捕获图像帧，请检查摄像头连接")
                        break
                    else:
                        self.error_occurred.emit(f"无法捕获图像帧 (错误 {consecutive_errors}/{max_consecutive_errors})")
            self.msleep(33)  # 约30fps
    
    def stop(self):
        """停止线程"""
        self.running = False
        self.wait()


class CameraManager:
    """相机管理器类，负责管理相机的连接、显示等功能"""
    
    def __init__(self, graphics_view):
        self.graphics_view = graphics_view
        self.camera = None
        self.camera_thread = None
        self.scene = None
        self.status_update_callback = None
        self.imgproc = None
        self.camera_type = None  # 'integrated' 或 'usb'
        
        # 性能监控相关变量
        self.frame_count = 0
        self.start_time = None
        self.actual_fps = 0.0
        self.last_frame_time = 0
        self.frame_times = []  # 用于计算平均帧时间
        self.max_frame_history = 30  # 保存最近30帧的时间
        
    def setup_graphics_view(self):
        """设置图形视图"""
        from PyQt5.QtGui import QPainter
        from PyQt5.QtWidgets import QGraphicsView
        
        # 创建场景
        self.scene = QGraphicsScene()
        self.graphics_view.setScene(self.scene)
        
        # 设置视图属性
        self.graphics_view.setRenderHint(QPainter.Antialiasing)
        self.graphics_view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        
    def start_integrated_camera(self, status_callback=None, camera_index=-1):
        """启动内置摄像头"""
        try:
            # 设置状态更新回调
            self.status_update_callback = status_callback
            
            # 初始化图像处理对象
            from .imgproc import Imgproc
            self.imgproc = Imgproc()
            
            # 查找可用的摄像头
            available_cameras = IntegratedCamera.find_available_cameras()
            if not available_cameras:
                if status_callback:
                    status_callback("未找到可用的摄像头", 5000)
                print("未找到可用的摄像头")
                return False
            
            # 如果camera_index为-1，使用默认逻辑选择内置摄像头
            if camera_index == -1:
                # 优先使用索引0（通常是内置摄像头）
                camera_index = 0 if 0 in available_cameras else available_cameras[0]
            elif camera_index not in available_cameras:
                # 如果指定的索引不可用，使用默认选择
                camera_index = 0 if 0 in available_cameras else available_cameras[0]
                print(f"指定的摄像头索引不可用，使用索引: {camera_index}")
            
            # 创建内置摄像头对象
            self.camera = IntegratedCamera()
            self.camera_type = 'integrated'
            
            # 连接摄像头
            if self.camera.connect(camera_index):
                # 设置图形视图
                self.setup_graphics_view()
                
                # 开始捕获
                self.camera.start_capture()
                
                # 创建并启动线程
                self.camera_thread = CameraThread(self.camera)
                self.camera_thread.frame_ready.connect(self.update_frame)
                self.camera_thread.error_occurred.connect(self.handle_error)
                self.camera_thread.start()
                
                print(f"内置摄像头启动成功 (索引: {camera_index})")
                return True
            else:
                print("无法启动内置摄像头")
                return False
        except Exception as e:
            print(f"启动内置摄像头时出错: {e}")
            return False
    
    def start_usb_camera(self, camera_index=1, status_callback=None):
        """启动USB摄像头"""
        try:
            # 设置状态更新回调
            self.status_update_callback = status_callback
            
            # 初始化图像处理对象
            from .imgproc import Imgproc
            self.imgproc = Imgproc()
            
            # 查找可用的摄像头
            available_cameras = IntegratedCamera.find_available_cameras()
            if not available_cameras:
                if status_callback:
                    status_callback("未找到可用的摄像头", 5000)
                print("未找到可用的摄像头")
                return False
            
            # 如果指定的索引不可用，尝试使用其他可用索引
            if camera_index not in available_cameras:
                # 优先选择非0索引（通常是USB摄像头）
                usb_cameras = [idx for idx in available_cameras if idx != 0]
                if usb_cameras:
                    camera_index = usb_cameras[0]
                else:
                    camera_index = available_cameras[0]
                print(f"指定的摄像头索引不可用，使用索引: {camera_index}")
            
            # 创建USB摄像头对象
            self.camera = USBCamera(camera_index)
            self.camera_type = 'usb'
            
            # 连接摄像头
            if self.camera.connect():
                # 设置图形视图
                self.setup_graphics_view()
                
                # 开始捕获
                self.camera.start_capture()
                
                # 创建并启动线程
                self.camera_thread = CameraThread(self.camera)
                self.camera_thread.frame_ready.connect(self.update_frame)
                self.camera_thread.error_occurred.connect(self.handle_error)
                self.camera_thread.start()
                
                print(f"USB摄像头 {camera_index} 启动成功")
                return True
            else:
                print(f"无法启动USB摄像头 {camera_index}")
                return False
        except Exception as e:
            print(f"启动USB摄像头时出错: {e}")
            return False
    
    def stop_camera(self):
        """停止摄像头"""
        if self.camera_thread:
            self.camera_thread.stop()
            self.camera_thread = None
        
        if self.camera:
            self.camera.stop_capture()
            self.camera.disconnect()
        
        print("摄像头已停止")
    
    def update_frame(self, frame):
        """更新显示的帧"""
        try:
            import time
            
            # 性能监控
            current_time = time.time()
            
            # 初始化开始时间
            if self.start_time is None:
                self.start_time = current_time
                self.last_frame_time = current_time
            
            # 计算帧间隔和FPS
            frame_interval = current_time - self.last_frame_time
            self.frame_times.append(frame_interval)
            
            # 保持帧时间历史在合理范围内
            if len(self.frame_times) > self.max_frame_history:
                self.frame_times.pop(0)
            
            # 计算平均FPS
            if len(self.frame_times) > 0:
                avg_frame_time = sum(self.frame_times) / len(self.frame_times)
                if avg_frame_time > 0:
                    self.actual_fps = 1.0 / avg_frame_time
            
            # 更新帧计数
            self.frame_count += 1
            self.last_frame_time = current_time
            
            # 计算FPS（使用图像处理对象的计算）
            imgproc_fps = self.imgproc.calculate_fps() if self.imgproc else 0
            
            # 获取图像信息
            height, width = frame.shape[:2] if frame is not None else (0, 0)
            
            # 更新状态栏信息
            if self.status_update_callback:
                camera_type_text = "内置摄像头" if self.camera_type == 'integrated' else "USB摄像头"
                status_info = (f"{camera_type_text}运行中 | "
                             f"分辨率: {width}x{height} | "
                             f"实际FPS: {self.actual_fps:.1f} | "
                             f"处理FPS: {imgproc_fps:.1f}")
                self.status_update_callback(status_info)
            
            # 将OpenCV帧转换为QPixmap
            pixmap = self.camera.convert_frame_to_qpixmap(frame)
            if pixmap:
                # 清除场景并添加新的图像
                self.scene.clear()
                self.scene.addPixmap(pixmap)
                
                # 调整视图以适应图像
                self.graphics_view.setSceneRect(QRectF(pixmap.rect()))
                self.graphics_view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        except Exception as e:
            print(f"更新帧时出错: {e}")
    
    def get_performance_stats(self):
        """获取性能统计信息"""
        stats = {
            'frame_count': self.frame_count,
            'actual_fps': self.actual_fps,
            'avg_frame_time': sum(self.frame_times) / len(self.frame_times) if self.frame_times else 0,
            'resolution': f"{self.camera.frame_width}x{self.camera.frame_height}" if self.camera else "未知",
            'camera_type': self.camera_type
        }
        return stats
    
    def handle_error(self, error_message):
        """处理错误"""
        print(f"摄像头错误: {error_message}")
    
    def resize_event(self):
        """处理窗口大小改变事件"""
        if self.scene:
            self.graphics_view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
    
    def save_current_frame(self, filename):
        """保存当前帧"""
        if self.camera.is_connected:
            frame = self.camera.capture_frame()
            if frame is not None:
                return self.camera.save_image(frame, filename)
        return False
    
    def get_camera_status(self):
        """获取摄像头状态"""
        return {
            'connected': self.camera.is_connected,
            'capturing': self.camera.is_capturing,
            'info': self.camera.get_camera_info() if self.camera.is_connected else None
        }
    
    def apply_resolution_change(self, width, height, fps):
        """应用分辨率改变，保持视场不变"""
        try:
            if not self.camera or not self.camera.is_connected:
                print("摄像头未连接，无法应用分辨率改变")
                return False
            
            print(f"正在应用分辨率改变: {width}x{height} @ {fps} FPS")
            
            # 记录当前视场状态
            current_view_rect = self.graphics_view.sceneRect() if self.scene else None
            current_transform = self.graphics_view.transform()
            
            # 应用分辨率设置
            resolution_success = self.camera.set_resolution(width, height)
            fps_success = self.camera.set_fps(fps)
            
            if resolution_success or fps_success:
                print("分辨率设置已应用")
                
                # 等待一帧以确保新设置生效
                import time
                time.sleep(0.1)
                
                # 获取新的摄像头信息
                info = self.camera.get_camera_info()
                if info:
                    print(f"新设置: {info['width']}x{info['height']} @ {info['fps']} FPS")
                
                # 保持视场不变 - 在下一帧更新时会自动调整
                # 这里不需要手动调整，因为update_frame方法会自动调用fitInView
                
                return True
            else:
                print("分辨率设置失败")
                return False
                
        except Exception as e:
            print(f"应用分辨率改变时出错: {e}")
            return False
